export interface GuestLoginReq {
  guest_key: string;
}

export function encodeGuestLoginReq(message: GuestLoginReq): Uint8Array {
  let bb = popByteBuffer();
  _encodeGuestLoginReq(message, bb);
  return toUint8Array(bb);
}

function _encodeGuestLoginReq(message: GuestLoginReq, bb: ByteBuffer): void {
  // required string guest_key = 1;
  let $guest_key = message.guest_key;
  if ($guest_key !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $guest_key);
  }
}

export function decodeGuestLoginReq(binary: Uint8Array): GuestLoginReq {
  return _decodeGuestLoginReq(wrapByteBuffer(binary));
}

function _decodeGuestLoginReq(bb: ByteBuffer): GuestLoginReq {
  let message: GuestLoginReq = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string guest_key = 1;
      case 1: {
        message.guest_key = readString(bb, readVarint32(bb));
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.guest_key === undefined)
    throw new Error("Missing required field: guest_key");

  return message;
}

export interface UnameLoginReq {
  uname: string;
  upwd: string;
}

export function encodeUnameLoginReq(message: UnameLoginReq): Uint8Array {
  let bb = popByteBuffer();
  _encodeUnameLoginReq(message, bb);
  return toUint8Array(bb);
}

function _encodeUnameLoginReq(message: UnameLoginReq, bb: ByteBuffer): void {
  // required string uname = 1;
  let $uname = message.uname;
  if ($uname !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $uname);
  }

  // required string upwd = 2;
  let $upwd = message.upwd;
  if ($upwd !== undefined) {
    writeVarint32(bb, 18);
    writeString(bb, $upwd);
  }
}

export function decodeUnameLoginReq(binary: Uint8Array): UnameLoginReq {
  return _decodeUnameLoginReq(wrapByteBuffer(binary));
}

function _decodeUnameLoginReq(bb: ByteBuffer): UnameLoginReq {
  let message: UnameLoginReq = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string uname = 1;
      case 1: {
        message.uname = readString(bb, readVarint32(bb));
        break;
      }

      // required string upwd = 2;
      case 2: {
        message.upwd = readString(bb, readVarint32(bb));
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.uname === undefined)
    throw new Error("Missing required field: uname");

  if (message.upwd === undefined)
    throw new Error("Missing required field: upwd");

  return message;
}

export interface UserCenterInfo {
  unick: string;
  uface: number;
  usex: number;
  uvip: number;
  uid: number;
}

export function encodeUserCenterInfo(message: UserCenterInfo): Uint8Array {
  let bb = popByteBuffer();
  _encodeUserCenterInfo(message, bb);
  return toUint8Array(bb);
}

function _encodeUserCenterInfo(message: UserCenterInfo, bb: ByteBuffer): void {
  // required string unick = 1;
  let $unick = message.unick;
  if ($unick !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $unick);
  }

  // required int32 uface = 2;
  let $uface = message.uface;
  if ($uface !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($uface));
  }

  // required int32 usex = 3;
  let $usex = message.usex;
  if ($usex !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($usex));
  }

  // required int32 uvip = 4;
  let $uvip = message.uvip;
  if ($uvip !== undefined) {
    writeVarint32(bb, 32);
    writeVarint64(bb, intToLong($uvip));
  }

  // required int32 uid = 5;
  let $uid = message.uid;
  if ($uid !== undefined) {
    writeVarint32(bb, 40);
    writeVarint64(bb, intToLong($uid));
  }
}

export function decodeUserCenterInfo(binary: Uint8Array): UserCenterInfo {
  return _decodeUserCenterInfo(wrapByteBuffer(binary));
}

function _decodeUserCenterInfo(bb: ByteBuffer): UserCenterInfo {
  let message: UserCenterInfo = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string unick = 1;
      case 1: {
        message.unick = readString(bb, readVarint32(bb));
        break;
      }

      // required int32 uface = 2;
      case 2: {
        message.uface = readVarint32(bb);
        break;
      }

      // required int32 usex = 3;
      case 3: {
        message.usex = readVarint32(bb);
        break;
      }

      // required int32 uvip = 4;
      case 4: {
        message.uvip = readVarint32(bb);
        break;
      }

      // required int32 uid = 5;
      case 5: {
        message.uid = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.unick === undefined)
    throw new Error("Missing required field: unick");

  if (message.uface === undefined)
    throw new Error("Missing required field: uface");

  if (message.usex === undefined)
    throw new Error("Missing required field: usex");

  if (message.uvip === undefined)
    throw new Error("Missing required field: uvip");

  if (message.uid === undefined)
    throw new Error("Missing required field: uid");

  return message;
}

export interface GuestLoginRes {
  status: number;
  uinfo?: UserCenterInfo;
}

export function encodeGuestLoginRes(message: GuestLoginRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeGuestLoginRes(message, bb);
  return toUint8Array(bb);
}

function _encodeGuestLoginRes(message: GuestLoginRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }

  // optional UserCenterInfo uinfo = 2;
  let $uinfo = message.uinfo;
  if ($uinfo !== undefined) {
    writeVarint32(bb, 18);
    let nested = popByteBuffer();
    _encodeUserCenterInfo($uinfo, nested);
    writeVarint32(bb, nested.limit);
    writeByteBuffer(bb, nested);
    pushByteBuffer(nested);
  }
}

export function decodeGuestLoginRes(binary: Uint8Array): GuestLoginRes {
  return _decodeGuestLoginRes(wrapByteBuffer(binary));
}

function _decodeGuestLoginRes(bb: ByteBuffer): GuestLoginRes {
  let message: GuestLoginRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      // optional UserCenterInfo uinfo = 2;
      case 2: {
        let limit = pushTemporaryLength(bb);
        message.uinfo = _decodeUserCenterInfo(bb);
        bb.limit = limit;
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface UnameLoginRes {
  status: number;
  uinfo?: UserCenterInfo;
}

export function encodeUnameLoginRes(message: UnameLoginRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeUnameLoginRes(message, bb);
  return toUint8Array(bb);
}

function _encodeUnameLoginRes(message: UnameLoginRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }

  // optional UserCenterInfo uinfo = 2;
  let $uinfo = message.uinfo;
  if ($uinfo !== undefined) {
    writeVarint32(bb, 18);
    let nested = popByteBuffer();
    _encodeUserCenterInfo($uinfo, nested);
    writeVarint32(bb, nested.limit);
    writeByteBuffer(bb, nested);
    pushByteBuffer(nested);
  }
}

export function decodeUnameLoginRes(binary: Uint8Array): UnameLoginRes {
  return _decodeUnameLoginRes(wrapByteBuffer(binary));
}

function _decodeUnameLoginRes(bb: ByteBuffer): UnameLoginRes {
  let message: UnameLoginRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      // optional UserCenterInfo uinfo = 2;
      case 2: {
        let limit = pushTemporaryLength(bb);
        message.uinfo = _decodeUserCenterInfo(bb);
        bb.limit = limit;
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface EditProfileReq {
  unick: string;
  uface: number;
  usex: number;
}

export function encodeEditProfileReq(message: EditProfileReq): Uint8Array {
  let bb = popByteBuffer();
  _encodeEditProfileReq(message, bb);
  return toUint8Array(bb);
}

function _encodeEditProfileReq(message: EditProfileReq, bb: ByteBuffer): void {
  // required string unick = 1;
  let $unick = message.unick;
  if ($unick !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $unick);
  }

  // required int32 uface = 2;
  let $uface = message.uface;
  if ($uface !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($uface));
  }

  // required int32 usex = 3;
  let $usex = message.usex;
  if ($usex !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($usex));
  }
}

export function decodeEditProfileReq(binary: Uint8Array): EditProfileReq {
  return _decodeEditProfileReq(wrapByteBuffer(binary));
}

function _decodeEditProfileReq(bb: ByteBuffer): EditProfileReq {
  let message: EditProfileReq = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string unick = 1;
      case 1: {
        message.unick = readString(bb, readVarint32(bb));
        break;
      }

      // required int32 uface = 2;
      case 2: {
        message.uface = readVarint32(bb);
        break;
      }

      // required int32 usex = 3;
      case 3: {
        message.usex = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.unick === undefined)
    throw new Error("Missing required field: unick");

  if (message.uface === undefined)
    throw new Error("Missing required field: uface");

  if (message.usex === undefined)
    throw new Error("Missing required field: usex");

  return message;
}

export interface EditProfileRes {
  status: number;
}

export function encodeEditProfileRes(message: EditProfileRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeEditProfileRes(message, bb);
  return toUint8Array(bb);
}

function _encodeEditProfileRes(message: EditProfileRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }
}

export function decodeEditProfileRes(binary: Uint8Array): EditProfileRes {
  return _decodeEditProfileRes(wrapByteBuffer(binary));
}

function _decodeEditProfileRes(bb: ByteBuffer): EditProfileRes {
  let message: EditProfileRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface AccountUpgradeReq {
  uname: string;
  upwd_md5: string;
}

export function encodeAccountUpgradeReq(message: AccountUpgradeReq): Uint8Array {
  let bb = popByteBuffer();
  _encodeAccountUpgradeReq(message, bb);
  return toUint8Array(bb);
}

function _encodeAccountUpgradeReq(message: AccountUpgradeReq, bb: ByteBuffer): void {
  // required string uname = 1;
  let $uname = message.uname;
  if ($uname !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $uname);
  }

  // required string upwd_md5 = 2;
  let $upwd_md5 = message.upwd_md5;
  if ($upwd_md5 !== undefined) {
    writeVarint32(bb, 18);
    writeString(bb, $upwd_md5);
  }
}

export function decodeAccountUpgradeReq(binary: Uint8Array): AccountUpgradeReq {
  return _decodeAccountUpgradeReq(wrapByteBuffer(binary));
}

function _decodeAccountUpgradeReq(bb: ByteBuffer): AccountUpgradeReq {
  let message: AccountUpgradeReq = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string uname = 1;
      case 1: {
        message.uname = readString(bb, readVarint32(bb));
        break;
      }

      // required string upwd_md5 = 2;
      case 2: {
        message.upwd_md5 = readString(bb, readVarint32(bb));
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.uname === undefined)
    throw new Error("Missing required field: uname");

  if (message.upwd_md5 === undefined)
    throw new Error("Missing required field: upwd_md5");

  return message;
}

export interface AccountUpgradeRes {
  status: number;
}

export function encodeAccountUpgradeRes(message: AccountUpgradeRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeAccountUpgradeRes(message, bb);
  return toUint8Array(bb);
}

function _encodeAccountUpgradeRes(message: AccountUpgradeRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }
}

export function decodeAccountUpgradeRes(binary: Uint8Array): AccountUpgradeRes {
  return _decodeAccountUpgradeRes(wrapByteBuffer(binary));
}

function _decodeAccountUpgradeRes(bb: ByteBuffer): AccountUpgradeRes {
  let message: AccountUpgradeRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface LoginOutRes {
  status: number;
}

export function encodeLoginOutRes(message: LoginOutRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeLoginOutRes(message, bb);
  return toUint8Array(bb);
}

function _encodeLoginOutRes(message: LoginOutRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }
}

export function decodeLoginOutRes(binary: Uint8Array): LoginOutRes {
  return _decodeLoginOutRes(wrapByteBuffer(binary));
}

function _decodeLoginOutRes(bb: ByteBuffer): LoginOutRes {
  let message: LoginOutRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface UserGameInfo {
  uchip: number;
  uexp: number;
  uvip: number;
  uchip2: number;
  uchip3: number;
  udata1: number;
  udata2: number;
  udata3: number;
  bonues_status: number;
  bonues: number;
  days: number;
}

export function encodeUserGameInfo(message: UserGameInfo): Uint8Array {
  let bb = popByteBuffer();
  _encodeUserGameInfo(message, bb);
  return toUint8Array(bb);
}

function _encodeUserGameInfo(message: UserGameInfo, bb: ByteBuffer): void {
  // required int32 uchip = 1;
  let $uchip = message.uchip;
  if ($uchip !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($uchip));
  }

  // required int32 uexp = 2;
  let $uexp = message.uexp;
  if ($uexp !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($uexp));
  }

  // required int32 uvip = 3;
  let $uvip = message.uvip;
  if ($uvip !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($uvip));
  }

  // required int32 uchip2 = 4;
  let $uchip2 = message.uchip2;
  if ($uchip2 !== undefined) {
    writeVarint32(bb, 32);
    writeVarint64(bb, intToLong($uchip2));
  }

  // required int32 uchip3 = 5;
  let $uchip3 = message.uchip3;
  if ($uchip3 !== undefined) {
    writeVarint32(bb, 40);
    writeVarint64(bb, intToLong($uchip3));
  }

  // required int32 udata1 = 6;
  let $udata1 = message.udata1;
  if ($udata1 !== undefined) {
    writeVarint32(bb, 48);
    writeVarint64(bb, intToLong($udata1));
  }

  // required int32 udata2 = 7;
  let $udata2 = message.udata2;
  if ($udata2 !== undefined) {
    writeVarint32(bb, 56);
    writeVarint64(bb, intToLong($udata2));
  }

  // required int32 udata3 = 8;
  let $udata3 = message.udata3;
  if ($udata3 !== undefined) {
    writeVarint32(bb, 64);
    writeVarint64(bb, intToLong($udata3));
  }

  // required int32 bonues_status = 9;
  let $bonues_status = message.bonues_status;
  if ($bonues_status !== undefined) {
    writeVarint32(bb, 72);
    writeVarint64(bb, intToLong($bonues_status));
  }

  // required int32 bonues = 10;
  let $bonues = message.bonues;
  if ($bonues !== undefined) {
    writeVarint32(bb, 80);
    writeVarint64(bb, intToLong($bonues));
  }

  // required int32 days = 11;
  let $days = message.days;
  if ($days !== undefined) {
    writeVarint32(bb, 88);
    writeVarint64(bb, intToLong($days));
  }
}

export function decodeUserGameInfo(binary: Uint8Array): UserGameInfo {
  return _decodeUserGameInfo(wrapByteBuffer(binary));
}

function _decodeUserGameInfo(bb: ByteBuffer): UserGameInfo {
  let message: UserGameInfo = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 uchip = 1;
      case 1: {
        message.uchip = readVarint32(bb);
        break;
      }

      // required int32 uexp = 2;
      case 2: {
        message.uexp = readVarint32(bb);
        break;
      }

      // required int32 uvip = 3;
      case 3: {
        message.uvip = readVarint32(bb);
        break;
      }

      // required int32 uchip2 = 4;
      case 4: {
        message.uchip2 = readVarint32(bb);
        break;
      }

      // required int32 uchip3 = 5;
      case 5: {
        message.uchip3 = readVarint32(bb);
        break;
      }

      // required int32 udata1 = 6;
      case 6: {
        message.udata1 = readVarint32(bb);
        break;
      }

      // required int32 udata2 = 7;
      case 7: {
        message.udata2 = readVarint32(bb);
        break;
      }

      // required int32 udata3 = 8;
      case 8: {
        message.udata3 = readVarint32(bb);
        break;
      }

      // required int32 bonues_status = 9;
      case 9: {
        message.bonues_status = readVarint32(bb);
        break;
      }

      // required int32 bonues = 10;
      case 10: {
        message.bonues = readVarint32(bb);
        break;
      }

      // required int32 days = 11;
      case 11: {
        message.days = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.uchip === undefined)
    throw new Error("Missing required field: uchip");

  if (message.uexp === undefined)
    throw new Error("Missing required field: uexp");

  if (message.uvip === undefined)
    throw new Error("Missing required field: uvip");

  if (message.uchip2 === undefined)
    throw new Error("Missing required field: uchip2");

  if (message.uchip3 === undefined)
    throw new Error("Missing required field: uchip3");

  if (message.udata1 === undefined)
    throw new Error("Missing required field: udata1");

  if (message.udata2 === undefined)
    throw new Error("Missing required field: udata2");

  if (message.udata3 === undefined)
    throw new Error("Missing required field: udata3");

  if (message.bonues_status === undefined)
    throw new Error("Missing required field: bonues_status");

  if (message.bonues === undefined)
    throw new Error("Missing required field: bonues");

  if (message.days === undefined)
    throw new Error("Missing required field: days");

  return message;
}

export interface GetUgameInfoRes {
  status: number;
  uinfo?: UserGameInfo;
}

export function encodeGetUgameInfoRes(message: GetUgameInfoRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeGetUgameInfoRes(message, bb);
  return toUint8Array(bb);
}

function _encodeGetUgameInfoRes(message: GetUgameInfoRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }

  // optional UserGameInfo uinfo = 2;
  let $uinfo = message.uinfo;
  if ($uinfo !== undefined) {
    writeVarint32(bb, 18);
    let nested = popByteBuffer();
    _encodeUserGameInfo($uinfo, nested);
    writeVarint32(bb, nested.limit);
    writeByteBuffer(bb, nested);
    pushByteBuffer(nested);
  }
}

export function decodeGetUgameInfoRes(binary: Uint8Array): GetUgameInfoRes {
  return _decodeGetUgameInfoRes(wrapByteBuffer(binary));
}

function _decodeGetUgameInfoRes(bb: ByteBuffer): GetUgameInfoRes {
  let message: GetUgameInfoRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      // optional UserGameInfo uinfo = 2;
      case 2: {
        let limit = pushTemporaryLength(bb);
        message.uinfo = _decodeUserGameInfo(bb);
        bb.limit = limit;
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface RecvLoginBonuesRes {
  status: number;
}

export function encodeRecvLoginBonuesRes(message: RecvLoginBonuesRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeRecvLoginBonuesRes(message, bb);
  return toUint8Array(bb);
}

function _encodeRecvLoginBonuesRes(message: RecvLoginBonuesRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }
}

export function decodeRecvLoginBonuesRes(binary: Uint8Array): RecvLoginBonuesRes {
  return _decodeRecvLoginBonuesRes(wrapByteBuffer(binary));
}

function _decodeRecvLoginBonuesRes(bb: ByteBuffer): RecvLoginBonuesRes {
  let message: RecvLoginBonuesRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface WorldChipRankInfo {
  unick: string;
  uface: number;
  usex: number;
  uvip: number;
  uchip: number;
}

export function encodeWorldChipRankInfo(message: WorldChipRankInfo): Uint8Array {
  let bb = popByteBuffer();
  _encodeWorldChipRankInfo(message, bb);
  return toUint8Array(bb);
}

function _encodeWorldChipRankInfo(message: WorldChipRankInfo, bb: ByteBuffer): void {
  // required string unick = 1;
  let $unick = message.unick;
  if ($unick !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $unick);
  }

  // required int32 uface = 2;
  let $uface = message.uface;
  if ($uface !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($uface));
  }

  // required int32 usex = 3;
  let $usex = message.usex;
  if ($usex !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($usex));
  }

  // required int32 uvip = 4;
  let $uvip = message.uvip;
  if ($uvip !== undefined) {
    writeVarint32(bb, 32);
    writeVarint64(bb, intToLong($uvip));
  }

  // required int32 uchip = 5;
  let $uchip = message.uchip;
  if ($uchip !== undefined) {
    writeVarint32(bb, 40);
    writeVarint64(bb, intToLong($uchip));
  }
}

export function decodeWorldChipRankInfo(binary: Uint8Array): WorldChipRankInfo {
  return _decodeWorldChipRankInfo(wrapByteBuffer(binary));
}

function _decodeWorldChipRankInfo(bb: ByteBuffer): WorldChipRankInfo {
  let message: WorldChipRankInfo = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string unick = 1;
      case 1: {
        message.unick = readString(bb, readVarint32(bb));
        break;
      }

      // required int32 uface = 2;
      case 2: {
        message.uface = readVarint32(bb);
        break;
      }

      // required int32 usex = 3;
      case 3: {
        message.usex = readVarint32(bb);
        break;
      }

      // required int32 uvip = 4;
      case 4: {
        message.uvip = readVarint32(bb);
        break;
      }

      // required int32 uchip = 5;
      case 5: {
        message.uchip = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.unick === undefined)
    throw new Error("Missing required field: unick");

  if (message.uface === undefined)
    throw new Error("Missing required field: uface");

  if (message.usex === undefined)
    throw new Error("Missing required field: usex");

  if (message.uvip === undefined)
    throw new Error("Missing required field: uvip");

  if (message.uchip === undefined)
    throw new Error("Missing required field: uchip");

  return message;
}

export interface GetWorldRankUchipRes {
  status: number;
  rank_info?: WorldChipRankInfo[];
}

export function encodeGetWorldRankUchipRes(message: GetWorldRankUchipRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeGetWorldRankUchipRes(message, bb);
  return toUint8Array(bb);
}

function _encodeGetWorldRankUchipRes(message: GetWorldRankUchipRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }

  // repeated WorldChipRankInfo rank_info = 2;
  let array$rank_info = message.rank_info;
  if (array$rank_info !== undefined) {
    for (let value of array$rank_info) {
      writeVarint32(bb, 18);
      let nested = popByteBuffer();
      _encodeWorldChipRankInfo(value, nested);
      writeVarint32(bb, nested.limit);
      writeByteBuffer(bb, nested);
      pushByteBuffer(nested);
    }
  }
}

export function decodeGetWorldRankUchipRes(binary: Uint8Array): GetWorldRankUchipRes {
  return _decodeGetWorldRankUchipRes(wrapByteBuffer(binary));
}

function _decodeGetWorldRankUchipRes(bb: ByteBuffer): GetWorldRankUchipRes {
  let message: GetWorldRankUchipRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      // repeated WorldChipRankInfo rank_info = 2;
      case 2: {
        let limit = pushTemporaryLength(bb);
        let values = message.rank_info || (message.rank_info = []);
        values.push(_decodeWorldChipRankInfo(bb));
        bb.limit = limit;
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface GetSysMsgReq {
  ver_num: number;
}

export function encodeGetSysMsgReq(message: GetSysMsgReq): Uint8Array {
  let bb = popByteBuffer();
  _encodeGetSysMsgReq(message, bb);
  return toUint8Array(bb);
}

function _encodeGetSysMsgReq(message: GetSysMsgReq, bb: ByteBuffer): void {
  // required int32 ver_num = 1;
  let $ver_num = message.ver_num;
  if ($ver_num !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($ver_num));
  }
}

export function decodeGetSysMsgReq(binary: Uint8Array): GetSysMsgReq {
  return _decodeGetSysMsgReq(wrapByteBuffer(binary));
}

function _decodeGetSysMsgReq(bb: ByteBuffer): GetSysMsgReq {
  let message: GetSysMsgReq = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 ver_num = 1;
      case 1: {
        message.ver_num = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.ver_num === undefined)
    throw new Error("Missing required field: ver_num");

  return message;
}

export interface GetSysMsgRes {
  status: number;
  ver_num: number;
  sys_msgs?: string[];
}

export function encodeGetSysMsgRes(message: GetSysMsgRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeGetSysMsgRes(message, bb);
  return toUint8Array(bb);
}

function _encodeGetSysMsgRes(message: GetSysMsgRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }

  // required int32 ver_num = 2;
  let $ver_num = message.ver_num;
  if ($ver_num !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($ver_num));
  }

  // repeated string sys_msgs = 3;
  let array$sys_msgs = message.sys_msgs;
  if (array$sys_msgs !== undefined) {
    for (let value of array$sys_msgs) {
      writeVarint32(bb, 26);
      writeString(bb, value);
    }
  }
}

export function decodeGetSysMsgRes(binary: Uint8Array): GetSysMsgRes {
  return _decodeGetSysMsgRes(wrapByteBuffer(binary));
}

function _decodeGetSysMsgRes(bb: ByteBuffer): GetSysMsgRes {
  let message: GetSysMsgRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      // required int32 ver_num = 2;
      case 2: {
        message.ver_num = readVarint32(bb);
        break;
      }

      // repeated string sys_msgs = 3;
      case 3: {
        let values = message.sys_msgs || (message.sys_msgs = []);
        values.push(readString(bb, readVarint32(bb)));
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  if (message.ver_num === undefined)
    throw new Error("Missing required field: ver_num");

  return message;
}

export interface LoginLogicRes {
  status: number;
}

export function encodeLoginLogicRes(message: LoginLogicRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeLoginLogicRes(message, bb);
  return toUint8Array(bb);
}

function _encodeLoginLogicRes(message: LoginLogicRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }
}

export function decodeLoginLogicRes(binary: Uint8Array): LoginLogicRes {
  return _decodeLoginLogicRes(wrapByteBuffer(binary));
}

function _decodeLoginLogicRes(bb: ByteBuffer): LoginLogicRes {
  let message: LoginLogicRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface EnterZoneReq {
  zid: number;
}

export function encodeEnterZoneReq(message: EnterZoneReq): Uint8Array {
  let bb = popByteBuffer();
  _encodeEnterZoneReq(message, bb);
  return toUint8Array(bb);
}

function _encodeEnterZoneReq(message: EnterZoneReq, bb: ByteBuffer): void {
  // required int32 zid = 1;
  let $zid = message.zid;
  if ($zid !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($zid));
  }
}

export function decodeEnterZoneReq(binary: Uint8Array): EnterZoneReq {
  return _decodeEnterZoneReq(wrapByteBuffer(binary));
}

function _decodeEnterZoneReq(bb: ByteBuffer): EnterZoneReq {
  let message: EnterZoneReq = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 zid = 1;
      case 1: {
        message.zid = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.zid === undefined)
    throw new Error("Missing required field: zid");

  return message;
}

export interface EnterZoneRes {
  status: number;
}

export function encodeEnterZoneRes(message: EnterZoneRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeEnterZoneRes(message, bb);
  return toUint8Array(bb);
}

function _encodeEnterZoneRes(message: EnterZoneRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }
}

export function decodeEnterZoneRes(binary: Uint8Array): EnterZoneRes {
  return _decodeEnterZoneRes(wrapByteBuffer(binary));
}

function _decodeEnterZoneRes(bb: ByteBuffer): EnterZoneRes {
  let message: EnterZoneRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface EnterMatch {
  zid: number;
  matchid: number;
  seatid: number;
  side: number;
}

export function encodeEnterMatch(message: EnterMatch): Uint8Array {
  let bb = popByteBuffer();
  _encodeEnterMatch(message, bb);
  return toUint8Array(bb);
}

function _encodeEnterMatch(message: EnterMatch, bb: ByteBuffer): void {
  // required int32 zid = 1;
  let $zid = message.zid;
  if ($zid !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($zid));
  }

  // required int32 matchid = 2;
  let $matchid = message.matchid;
  if ($matchid !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($matchid));
  }

  // required int32 seatid = 3;
  let $seatid = message.seatid;
  if ($seatid !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($seatid));
  }

  // required int32 side = 4;
  let $side = message.side;
  if ($side !== undefined) {
    writeVarint32(bb, 32);
    writeVarint64(bb, intToLong($side));
  }
}

export function decodeEnterMatch(binary: Uint8Array): EnterMatch {
  return _decodeEnterMatch(wrapByteBuffer(binary));
}

function _decodeEnterMatch(bb: ByteBuffer): EnterMatch {
  let message: EnterMatch = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 zid = 1;
      case 1: {
        message.zid = readVarint32(bb);
        break;
      }

      // required int32 matchid = 2;
      case 2: {
        message.matchid = readVarint32(bb);
        break;
      }

      // required int32 seatid = 3;
      case 3: {
        message.seatid = readVarint32(bb);
        break;
      }

      // required int32 side = 4;
      case 4: {
        message.side = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.zid === undefined)
    throw new Error("Missing required field: zid");

  if (message.matchid === undefined)
    throw new Error("Missing required field: matchid");

  if (message.seatid === undefined)
    throw new Error("Missing required field: seatid");

  if (message.side === undefined)
    throw new Error("Missing required field: side");

  return message;
}

export interface UserArrived {
  unick: string;
  uface: number;
  usex: number;
  seatid: number;
  side: number;
}

export function encodeUserArrived(message: UserArrived): Uint8Array {
  let bb = popByteBuffer();
  _encodeUserArrived(message, bb);
  return toUint8Array(bb);
}

function _encodeUserArrived(message: UserArrived, bb: ByteBuffer): void {
  // required string unick = 1;
  let $unick = message.unick;
  if ($unick !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $unick);
  }

  // required int32 uface = 2;
  let $uface = message.uface;
  if ($uface !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($uface));
  }

  // required int32 usex = 3;
  let $usex = message.usex;
  if ($usex !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($usex));
  }

  // required int32 seatid = 4;
  let $seatid = message.seatid;
  if ($seatid !== undefined) {
    writeVarint32(bb, 32);
    writeVarint64(bb, intToLong($seatid));
  }

  // required int32 side = 5;
  let $side = message.side;
  if ($side !== undefined) {
    writeVarint32(bb, 40);
    writeVarint64(bb, intToLong($side));
  }
}

export function decodeUserArrived(binary: Uint8Array): UserArrived {
  return _decodeUserArrived(wrapByteBuffer(binary));
}

function _decodeUserArrived(bb: ByteBuffer): UserArrived {
  let message: UserArrived = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string unick = 1;
      case 1: {
        message.unick = readString(bb, readVarint32(bb));
        break;
      }

      // required int32 uface = 2;
      case 2: {
        message.uface = readVarint32(bb);
        break;
      }

      // required int32 usex = 3;
      case 3: {
        message.usex = readVarint32(bb);
        break;
      }

      // required int32 seatid = 4;
      case 4: {
        message.seatid = readVarint32(bb);
        break;
      }

      // required int32 side = 5;
      case 5: {
        message.side = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.unick === undefined)
    throw new Error("Missing required field: unick");

  if (message.uface === undefined)
    throw new Error("Missing required field: uface");

  if (message.usex === undefined)
    throw new Error("Missing required field: usex");

  if (message.seatid === undefined)
    throw new Error("Missing required field: seatid");

  if (message.side === undefined)
    throw new Error("Missing required field: side");

  return message;
}

export interface ExitMatchRes {
  status: number;
}

export function encodeExitMatchRes(message: ExitMatchRes): Uint8Array {
  let bb = popByteBuffer();
  _encodeExitMatchRes(message, bb);
  return toUint8Array(bb);
}

function _encodeExitMatchRes(message: ExitMatchRes, bb: ByteBuffer): void {
  // required int32 status = 1;
  let $status = message.status;
  if ($status !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($status));
  }
}

export function decodeExitMatchRes(binary: Uint8Array): ExitMatchRes {
  return _decodeExitMatchRes(wrapByteBuffer(binary));
}

function _decodeExitMatchRes(bb: ByteBuffer): ExitMatchRes {
  let message: ExitMatchRes = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 status = 1;
      case 1: {
        message.status = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.status === undefined)
    throw new Error("Missing required field: status");

  return message;
}

export interface UserExitMatch {
  seatid: number;
}

export function encodeUserExitMatch(message: UserExitMatch): Uint8Array {
  let bb = popByteBuffer();
  _encodeUserExitMatch(message, bb);
  return toUint8Array(bb);
}

function _encodeUserExitMatch(message: UserExitMatch, bb: ByteBuffer): void {
  // required int32 seatid = 1;
  let $seatid = message.seatid;
  if ($seatid !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($seatid));
  }
}

export function decodeUserExitMatch(binary: Uint8Array): UserExitMatch {
  return _decodeUserExitMatch(wrapByteBuffer(binary));
}

function _decodeUserExitMatch(bb: ByteBuffer): UserExitMatch {
  let message: UserExitMatch = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 seatid = 1;
      case 1: {
        message.seatid = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.seatid === undefined)
    throw new Error("Missing required field: seatid");

  return message;
}

export interface PlayerMatchInfo {
  heroid: number;
  seatid: number;
  side: number;
}

export function encodePlayerMatchInfo(message: PlayerMatchInfo): Uint8Array {
  let bb = popByteBuffer();
  _encodePlayerMatchInfo(message, bb);
  return toUint8Array(bb);
}

function _encodePlayerMatchInfo(message: PlayerMatchInfo, bb: ByteBuffer): void {
  // required int32 heroid = 1;
  let $heroid = message.heroid;
  if ($heroid !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($heroid));
  }

  // required int32 seatid = 2;
  let $seatid = message.seatid;
  if ($seatid !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($seatid));
  }

  // required int32 side = 3;
  let $side = message.side;
  if ($side !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($side));
  }
}

export function decodePlayerMatchInfo(binary: Uint8Array): PlayerMatchInfo {
  return _decodePlayerMatchInfo(wrapByteBuffer(binary));
}

function _decodePlayerMatchInfo(bb: ByteBuffer): PlayerMatchInfo {
  let message: PlayerMatchInfo = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 heroid = 1;
      case 1: {
        message.heroid = readVarint32(bb);
        break;
      }

      // required int32 seatid = 2;
      case 2: {
        message.seatid = readVarint32(bb);
        break;
      }

      // required int32 side = 3;
      case 3: {
        message.side = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.heroid === undefined)
    throw new Error("Missing required field: heroid");

  if (message.seatid === undefined)
    throw new Error("Missing required field: seatid");

  if (message.side === undefined)
    throw new Error("Missing required field: side");

  return message;
}

export interface GameStart {
  players_match_info?: PlayerMatchInfo[];
}

export function encodeGameStart(message: GameStart): Uint8Array {
  let bb = popByteBuffer();
  _encodeGameStart(message, bb);
  return toUint8Array(bb);
}

function _encodeGameStart(message: GameStart, bb: ByteBuffer): void {
  // repeated PlayerMatchInfo players_match_info = 1;
  let array$players_match_info = message.players_match_info;
  if (array$players_match_info !== undefined) {
    for (let value of array$players_match_info) {
      writeVarint32(bb, 10);
      let nested = popByteBuffer();
      _encodePlayerMatchInfo(value, nested);
      writeVarint32(bb, nested.limit);
      writeByteBuffer(bb, nested);
      pushByteBuffer(nested);
    }
  }
}

export function decodeGameStart(binary: Uint8Array): GameStart {
  return _decodeGameStart(wrapByteBuffer(binary));
}

function _decodeGameStart(bb: ByteBuffer): GameStart {
  let message: GameStart = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // repeated PlayerMatchInfo players_match_info = 1;
      case 1: {
        let limit = pushTemporaryLength(bb);
        let values = message.players_match_info || (message.players_match_info = []);
        values.push(_decodePlayerMatchInfo(bb));
        bb.limit = limit;
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  return message;
}

export interface UdpTest {
  content: string;
}

export function encodeUdpTest(message: UdpTest): Uint8Array {
  let bb = popByteBuffer();
  _encodeUdpTest(message, bb);
  return toUint8Array(bb);
}

function _encodeUdpTest(message: UdpTest, bb: ByteBuffer): void {
  // required string content = 1;
  let $content = message.content;
  if ($content !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $content);
  }
}

export function decodeUdpTest(binary: Uint8Array): UdpTest {
  return _decodeUdpTest(wrapByteBuffer(binary));
}

function _decodeUdpTest(bb: ByteBuffer): UdpTest {
  let message: UdpTest = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string content = 1;
      case 1: {
        message.content = readString(bb, readVarint32(bb));
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.content === undefined)
    throw new Error("Missing required field: content");

  return message;
}

export interface LoginLogicReq {
  udp_ip: string;
  udp_port: number;
}

export function encodeLoginLogicReq(message: LoginLogicReq): Uint8Array {
  let bb = popByteBuffer();
  _encodeLoginLogicReq(message, bb);
  return toUint8Array(bb);
}

function _encodeLoginLogicReq(message: LoginLogicReq, bb: ByteBuffer): void {
  // required string udp_ip = 1;
  let $udp_ip = message.udp_ip;
  if ($udp_ip !== undefined) {
    writeVarint32(bb, 10);
    writeString(bb, $udp_ip);
  }

  // required int32 udp_port = 2;
  let $udp_port = message.udp_port;
  if ($udp_port !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($udp_port));
  }
}

export function decodeLoginLogicReq(binary: Uint8Array): LoginLogicReq {
  return _decodeLoginLogicReq(wrapByteBuffer(binary));
}

function _decodeLoginLogicReq(bb: ByteBuffer): LoginLogicReq {
  let message: LoginLogicReq = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required string udp_ip = 1;
      case 1: {
        message.udp_ip = readString(bb, readVarint32(bb));
        break;
      }

      // required int32 udp_port = 2;
      case 2: {
        message.udp_port = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.udp_ip === undefined)
    throw new Error("Missing required field: udp_ip");

  if (message.udp_port === undefined)
    throw new Error("Missing required field: udp_port");

  return message;
}

export interface OptionEvent {
  seatid: number;
  opt_type: number;
  x?: number;
  y?: number;
}

export function encodeOptionEvent(message: OptionEvent): Uint8Array {
  let bb = popByteBuffer();
  _encodeOptionEvent(message, bb);
  return toUint8Array(bb);
}

function _encodeOptionEvent(message: OptionEvent, bb: ByteBuffer): void {
  // required int32 seatid = 1;
  let $seatid = message.seatid;
  if ($seatid !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($seatid));
  }

  // required int32 opt_type = 2;
  let $opt_type = message.opt_type;
  if ($opt_type !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($opt_type));
  }

  // optional int32 x = 3;
  let $x = message.x;
  if ($x !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($x));
  }

  // optional int32 y = 4;
  let $y = message.y;
  if ($y !== undefined) {
    writeVarint32(bb, 32);
    writeVarint64(bb, intToLong($y));
  }
}

export function decodeOptionEvent(binary: Uint8Array): OptionEvent {
  return _decodeOptionEvent(wrapByteBuffer(binary));
}

function _decodeOptionEvent(bb: ByteBuffer): OptionEvent {
  let message: OptionEvent = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 seatid = 1;
      case 1: {
        message.seatid = readVarint32(bb);
        break;
      }

      // required int32 opt_type = 2;
      case 2: {
        message.opt_type = readVarint32(bb);
        break;
      }

      // optional int32 x = 3;
      case 3: {
        message.x = readVarint32(bb);
        break;
      }

      // optional int32 y = 4;
      case 4: {
        message.y = readVarint32(bb);
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.seatid === undefined)
    throw new Error("Missing required field: seatid");

  if (message.opt_type === undefined)
    throw new Error("Missing required field: opt_type");

  return message;
}

export interface FrameOpts {
  frameid: number;
  opts?: OptionEvent[];
}

export function encodeFrameOpts(message: FrameOpts): Uint8Array {
  let bb = popByteBuffer();
  _encodeFrameOpts(message, bb);
  return toUint8Array(bb);
}

function _encodeFrameOpts(message: FrameOpts, bb: ByteBuffer): void {
  // required int32 frameid = 1;
  let $frameid = message.frameid;
  if ($frameid !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($frameid));
  }

  // repeated OptionEvent opts = 2;
  let array$opts = message.opts;
  if (array$opts !== undefined) {
    for (let value of array$opts) {
      writeVarint32(bb, 18);
      let nested = popByteBuffer();
      _encodeOptionEvent(value, nested);
      writeVarint32(bb, nested.limit);
      writeByteBuffer(bb, nested);
      pushByteBuffer(nested);
    }
  }
}

export function decodeFrameOpts(binary: Uint8Array): FrameOpts {
  return _decodeFrameOpts(wrapByteBuffer(binary));
}

function _decodeFrameOpts(bb: ByteBuffer): FrameOpts {
  let message: FrameOpts = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 frameid = 1;
      case 1: {
        message.frameid = readVarint32(bb);
        break;
      }

      // repeated OptionEvent opts = 2;
      case 2: {
        let limit = pushTemporaryLength(bb);
        let values = message.opts || (message.opts = []);
        values.push(_decodeOptionEvent(bb));
        bb.limit = limit;
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.frameid === undefined)
    throw new Error("Missing required field: frameid");

  return message;
}

export interface LogicFrame {
  frameid: number;
  unsync_frames?: FrameOpts[];
}

export function encodeLogicFrame(message: LogicFrame): Uint8Array {
  let bb = popByteBuffer();
  _encodeLogicFrame(message, bb);
  return toUint8Array(bb);
}

function _encodeLogicFrame(message: LogicFrame, bb: ByteBuffer): void {
  // required int32 frameid = 1;
  let $frameid = message.frameid;
  if ($frameid !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($frameid));
  }

  // repeated FrameOpts unsync_frames = 2;
  let array$unsync_frames = message.unsync_frames;
  if (array$unsync_frames !== undefined) {
    for (let value of array$unsync_frames) {
      writeVarint32(bb, 18);
      let nested = popByteBuffer();
      _encodeFrameOpts(value, nested);
      writeVarint32(bb, nested.limit);
      writeByteBuffer(bb, nested);
      pushByteBuffer(nested);
    }
  }
}

export function decodeLogicFrame(binary: Uint8Array): LogicFrame {
  return _decodeLogicFrame(wrapByteBuffer(binary));
}

function _decodeLogicFrame(bb: ByteBuffer): LogicFrame {
  let message: LogicFrame = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 frameid = 1;
      case 1: {
        message.frameid = readVarint32(bb);
        break;
      }

      // repeated FrameOpts unsync_frames = 2;
      case 2: {
        let limit = pushTemporaryLength(bb);
        let values = message.unsync_frames || (message.unsync_frames = []);
        values.push(_decodeFrameOpts(bb));
        bb.limit = limit;
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.frameid === undefined)
    throw new Error("Missing required field: frameid");

  return message;
}

export interface NextFrameOpts {
  frameid: number;
  zid: number;
  matchid: number;
  seatid: number;
  opts?: OptionEvent[];
}

export function encodeNextFrameOpts(message: NextFrameOpts): Uint8Array {
  let bb = popByteBuffer();
  _encodeNextFrameOpts(message, bb);
  return toUint8Array(bb);
}

function _encodeNextFrameOpts(message: NextFrameOpts, bb: ByteBuffer): void {
  // required int32 frameid = 1;
  let $frameid = message.frameid;
  if ($frameid !== undefined) {
    writeVarint32(bb, 8);
    writeVarint64(bb, intToLong($frameid));
  }

  // required int32 zid = 2;
  let $zid = message.zid;
  if ($zid !== undefined) {
    writeVarint32(bb, 16);
    writeVarint64(bb, intToLong($zid));
  }

  // required int32 matchid = 3;
  let $matchid = message.matchid;
  if ($matchid !== undefined) {
    writeVarint32(bb, 24);
    writeVarint64(bb, intToLong($matchid));
  }

  // required int32 seatid = 4;
  let $seatid = message.seatid;
  if ($seatid !== undefined) {
    writeVarint32(bb, 32);
    writeVarint64(bb, intToLong($seatid));
  }

  // repeated OptionEvent opts = 5;
  let array$opts = message.opts;
  if (array$opts !== undefined) {
    for (let value of array$opts) {
      writeVarint32(bb, 42);
      let nested = popByteBuffer();
      _encodeOptionEvent(value, nested);
      writeVarint32(bb, nested.limit);
      writeByteBuffer(bb, nested);
      pushByteBuffer(nested);
    }
  }
}

export function decodeNextFrameOpts(binary: Uint8Array): NextFrameOpts {
  return _decodeNextFrameOpts(wrapByteBuffer(binary));
}

function _decodeNextFrameOpts(bb: ByteBuffer): NextFrameOpts {
  let message: NextFrameOpts = {} as any;

  end_of_message: while (!isAtEnd(bb)) {
    let tag = readVarint32(bb);

    switch (tag >>> 3) {
      case 0:
        break end_of_message;

      // required int32 frameid = 1;
      case 1: {
        message.frameid = readVarint32(bb);
        break;
      }

      // required int32 zid = 2;
      case 2: {
        message.zid = readVarint32(bb);
        break;
      }

      // required int32 matchid = 3;
      case 3: {
        message.matchid = readVarint32(bb);
        break;
      }

      // required int32 seatid = 4;
      case 4: {
        message.seatid = readVarint32(bb);
        break;
      }

      // repeated OptionEvent opts = 5;
      case 5: {
        let limit = pushTemporaryLength(bb);
        let values = message.opts || (message.opts = []);
        values.push(_decodeOptionEvent(bb));
        bb.limit = limit;
        break;
      }

      default:
        skipUnknownField(bb, tag & 7);
    }
  }

  if (message.frameid === undefined)
    throw new Error("Missing required field: frameid");

  if (message.zid === undefined)
    throw new Error("Missing required field: zid");

  if (message.matchid === undefined)
    throw new Error("Missing required field: matchid");

  if (message.seatid === undefined)
    throw new Error("Missing required field: seatid");

  return message;
}

export interface Long {
  low: number;
  high: number;
  unsigned: boolean;
}

interface ByteBuffer {
  bytes: Uint8Array;
  offset: number;
  limit: number;
}

function pushTemporaryLength(bb: ByteBuffer): number {
  let length = readVarint32(bb);
  let limit = bb.limit;
  bb.limit = bb.offset + length;
  return limit;
}

function skipUnknownField(bb: ByteBuffer, type: number): void {
  switch (type) {
    case 0: while (readByte(bb) & 0x80) { } break;
    case 2: skip(bb, readVarint32(bb)); break;
    case 5: skip(bb, 4); break;
    case 1: skip(bb, 8); break;
    default: throw new Error("Unimplemented type: " + type);
  }
}

function stringToLong(value: string): Long {
  return {
    low: value.charCodeAt(0) | (value.charCodeAt(1) << 16),
    high: value.charCodeAt(2) | (value.charCodeAt(3) << 16),
    unsigned: false,
  };
}

function longToString(value: Long): string {
  let low = value.low;
  let high = value.high;
  return String.fromCharCode(
    low & 0xFFFF,
    low >>> 16,
    high & 0xFFFF,
    high >>> 16);
}

// The code below was modified from https://github.com/protobufjs/bytebuffer.js
// which is under the Apache License 2.0.

let f32 = new Float32Array(1);
let f32_u8 = new Uint8Array(f32.buffer);

let f64 = new Float64Array(1);
let f64_u8 = new Uint8Array(f64.buffer);

function intToLong(value: number): Long {
  value |= 0;
  return {
    low: value,
    high: value >> 31,
    unsigned: value >= 0,
  };
}

let bbStack: ByteBuffer[] = [];

function popByteBuffer(): ByteBuffer {
  const bb = bbStack.pop();
  if (!bb) return { bytes: new Uint8Array(64), offset: 0, limit: 0 };
  bb.offset = bb.limit = 0;
  return bb;
}

function pushByteBuffer(bb: ByteBuffer): void {
  bbStack.push(bb);
}

function wrapByteBuffer(bytes: Uint8Array): ByteBuffer {
  return { bytes, offset: 0, limit: bytes.length };
}

function toUint8Array(bb: ByteBuffer): Uint8Array {
  let bytes = bb.bytes;
  let limit = bb.limit;
  return bytes.length === limit ? bytes : bytes.subarray(0, limit);
}

function skip(bb: ByteBuffer, offset: number): void {
  if (bb.offset + offset > bb.limit) {
    throw new Error('Skip past limit');
  }
  bb.offset += offset;
}

function isAtEnd(bb: ByteBuffer): boolean {
  return bb.offset >= bb.limit;
}

function grow(bb: ByteBuffer, count: number): number {
  let bytes = bb.bytes;
  let offset = bb.offset;
  let limit = bb.limit;
  let finalOffset = offset + count;
  if (finalOffset > bytes.length) {
    let newBytes = new Uint8Array(finalOffset * 2);
    newBytes.set(bytes);
    bb.bytes = newBytes;
  }
  bb.offset = finalOffset;
  if (finalOffset > limit) {
    bb.limit = finalOffset;
  }
  return offset;
}

function advance(bb: ByteBuffer, count: number): number {
  let offset = bb.offset;
  if (offset + count > bb.limit) {
    throw new Error('Read past limit');
  }
  bb.offset += count;
  return offset;
}

function readBytes(bb: ByteBuffer, count: number): Uint8Array {
  let offset = advance(bb, count);
  return bb.bytes.subarray(offset, offset + count);
}

function writeBytes(bb: ByteBuffer, buffer: Uint8Array): void {
  let offset = grow(bb, buffer.length);
  bb.bytes.set(buffer, offset);
}

function readString(bb: ByteBuffer, count: number): string {
  // Sadly a hand-coded UTF8 decoder is much faster than subarray+TextDecoder in V8
  let offset = advance(bb, count);
  let fromCharCode = String.fromCharCode;
  let bytes = bb.bytes;
  let invalid = '\uFFFD';
  let text = '';

  for (let i = 0; i < count; i++) {
    let c1 = bytes[i + offset], c2: number, c3: number, c4: number, c: number;

    // 1 byte
    if ((c1 & 0x80) === 0) {
      text += fromCharCode(c1);
    }

    // 2 bytes
    else if ((c1 & 0xE0) === 0xC0) {
      if (i + 1 >= count) text += invalid;
      else {
        c2 = bytes[i + offset + 1];
        if ((c2 & 0xC0) !== 0x80) text += invalid;
        else {
          c = ((c1 & 0x1F) << 6) | (c2 & 0x3F);
          if (c < 0x80) text += invalid;
          else {
            text += fromCharCode(c);
            i++;
          }
        }
      }
    }

    // 3 bytes
    else if ((c1 & 0xF0) == 0xE0) {
      if (i + 2 >= count) text += invalid;
      else {
        c2 = bytes[i + offset + 1];
        c3 = bytes[i + offset + 2];
        if (((c2 | (c3 << 8)) & 0xC0C0) !== 0x8080) text += invalid;
        else {
          c = ((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
          if (c < 0x0800 || (c >= 0xD800 && c <= 0xDFFF)) text += invalid;
          else {
            text += fromCharCode(c);
            i += 2;
          }
        }
      }
    }

    // 4 bytes
    else if ((c1 & 0xF8) == 0xF0) {
      if (i + 3 >= count) text += invalid;
      else {
        c2 = bytes[i + offset + 1];
        c3 = bytes[i + offset + 2];
        c4 = bytes[i + offset + 3];
        if (((c2 | (c3 << 8) | (c4 << 16)) & 0xC0C0C0) !== 0x808080) text += invalid;
        else {
          c = ((c1 & 0x07) << 0x12) | ((c2 & 0x3F) << 0x0C) | ((c3 & 0x3F) << 0x06) | (c4 & 0x3F);
          if (c < 0x10000 || c > 0x10FFFF) text += invalid;
          else {
            c -= 0x10000;
            text += fromCharCode((c >> 10) + 0xD800, (c & 0x3FF) + 0xDC00);
            i += 3;
          }
        }
      }
    }

    else text += invalid;
  }

  return text;
}

function writeString(bb: ByteBuffer, text: string): void {
  // Sadly a hand-coded UTF8 encoder is much faster than TextEncoder+set in V8
  let n = text.length;
  let byteCount = 0;

  // Write the byte count first
  for (let i = 0; i < n; i++) {
    let c = text.charCodeAt(i);
    if (c >= 0xD800 && c <= 0xDBFF && i + 1 < n) {
      c = (c << 10) + text.charCodeAt(++i) - 0x35FDC00;
    }
    byteCount += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
  }
  writeVarint32(bb, byteCount);

  let offset = grow(bb, byteCount);
  let bytes = bb.bytes;

  // Then write the bytes
  for (let i = 0; i < n; i++) {
    let c = text.charCodeAt(i);
    if (c >= 0xD800 && c <= 0xDBFF && i + 1 < n) {
      c = (c << 10) + text.charCodeAt(++i) - 0x35FDC00;
    }
    if (c < 0x80) {
      bytes[offset++] = c;
    } else {
      if (c < 0x800) {
        bytes[offset++] = ((c >> 6) & 0x1F) | 0xC0;
      } else {
        if (c < 0x10000) {
          bytes[offset++] = ((c >> 12) & 0x0F) | 0xE0;
        } else {
          bytes[offset++] = ((c >> 18) & 0x07) | 0xF0;
          bytes[offset++] = ((c >> 12) & 0x3F) | 0x80;
        }
        bytes[offset++] = ((c >> 6) & 0x3F) | 0x80;
      }
      bytes[offset++] = (c & 0x3F) | 0x80;
    }
  }
}

function writeByteBuffer(bb: ByteBuffer, buffer: ByteBuffer): void {
  let offset = grow(bb, buffer.limit);
  let from = bb.bytes;
  let to = buffer.bytes;

  // This for loop is much faster than subarray+set on V8
  for (let i = 0, n = buffer.limit; i < n; i++) {
    from[i + offset] = to[i];
  }
}

function readByte(bb: ByteBuffer): number {
  return bb.bytes[advance(bb, 1)];
}

function writeByte(bb: ByteBuffer, value: number): void {
  let offset = grow(bb, 1);
  bb.bytes[offset] = value;
}

function readFloat(bb: ByteBuffer): number {
  let offset = advance(bb, 4);
  let bytes = bb.bytes;

  // Manual copying is much faster than subarray+set in V8
  f32_u8[0] = bytes[offset++];
  f32_u8[1] = bytes[offset++];
  f32_u8[2] = bytes[offset++];
  f32_u8[3] = bytes[offset++];
  return f32[0];
}

function writeFloat(bb: ByteBuffer, value: number): void {
  let offset = grow(bb, 4);
  let bytes = bb.bytes;
  f32[0] = value;

  // Manual copying is much faster than subarray+set in V8
  bytes[offset++] = f32_u8[0];
  bytes[offset++] = f32_u8[1];
  bytes[offset++] = f32_u8[2];
  bytes[offset++] = f32_u8[3];
}

function readDouble(bb: ByteBuffer): number {
  let offset = advance(bb, 8);
  let bytes = bb.bytes;

  // Manual copying is much faster than subarray+set in V8
  f64_u8[0] = bytes[offset++];
  f64_u8[1] = bytes[offset++];
  f64_u8[2] = bytes[offset++];
  f64_u8[3] = bytes[offset++];
  f64_u8[4] = bytes[offset++];
  f64_u8[5] = bytes[offset++];
  f64_u8[6] = bytes[offset++];
  f64_u8[7] = bytes[offset++];
  return f64[0];
}

function writeDouble(bb: ByteBuffer, value: number): void {
  let offset = grow(bb, 8);
  let bytes = bb.bytes;
  f64[0] = value;

  // Manual copying is much faster than subarray+set in V8
  bytes[offset++] = f64_u8[0];
  bytes[offset++] = f64_u8[1];
  bytes[offset++] = f64_u8[2];
  bytes[offset++] = f64_u8[3];
  bytes[offset++] = f64_u8[4];
  bytes[offset++] = f64_u8[5];
  bytes[offset++] = f64_u8[6];
  bytes[offset++] = f64_u8[7];
}

function readInt32(bb: ByteBuffer): number {
  let offset = advance(bb, 4);
  let bytes = bb.bytes;
  return (
    bytes[offset] |
    (bytes[offset + 1] << 8) |
    (bytes[offset + 2] << 16) |
    (bytes[offset + 3] << 24)
  );
}

function writeInt32(bb: ByteBuffer, value: number): void {
  let offset = grow(bb, 4);
  let bytes = bb.bytes;
  bytes[offset] = value;
  bytes[offset + 1] = value >> 8;
  bytes[offset + 2] = value >> 16;
  bytes[offset + 3] = value >> 24;
}

function readInt64(bb: ByteBuffer, unsigned: boolean): Long {
  return {
    low: readInt32(bb),
    high: readInt32(bb),
    unsigned,
  };
}

function writeInt64(bb: ByteBuffer, value: Long): void {
  writeInt32(bb, value.low);
  writeInt32(bb, value.high);
}

function readVarint32(bb: ByteBuffer): number {
  let c = 0;
  let value = 0;
  let b: number;
  do {
    b = readByte(bb);
    if (c < 32) value |= (b & 0x7F) << c;
    c += 7;
  } while (b & 0x80);
  return value;
}

function writeVarint32(bb: ByteBuffer, value: number): void {
  value >>>= 0;
  while (value >= 0x80) {
    writeByte(bb, (value & 0x7f) | 0x80);
    value >>>= 7;
  }
  writeByte(bb, value);
}

function readVarint64(bb: ByteBuffer, unsigned: boolean): Long {
  let part0 = 0;
  let part1 = 0;
  let part2 = 0;
  let b: number;

  b = readByte(bb); part0 = (b & 0x7F); if (b & 0x80) {
    b = readByte(bb); part0 |= (b & 0x7F) << 7; if (b & 0x80) {
      b = readByte(bb); part0 |= (b & 0x7F) << 14; if (b & 0x80) {
        b = readByte(bb); part0 |= (b & 0x7F) << 21; if (b & 0x80) {

          b = readByte(bb); part1 = (b & 0x7F); if (b & 0x80) {
            b = readByte(bb); part1 |= (b & 0x7F) << 7; if (b & 0x80) {
              b = readByte(bb); part1 |= (b & 0x7F) << 14; if (b & 0x80) {
                b = readByte(bb); part1 |= (b & 0x7F) << 21; if (b & 0x80) {

                  b = readByte(bb); part2 = (b & 0x7F); if (b & 0x80) {
                    b = readByte(bb); part2 |= (b & 0x7F) << 7;
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  return {
    low: part0 | (part1 << 28),
    high: (part1 >>> 4) | (part2 << 24),
    unsigned,
  };
}

function writeVarint64(bb: ByteBuffer, value: Long): void {
  let part0 = value.low >>> 0;
  let part1 = ((value.low >>> 28) | (value.high << 4)) >>> 0;
  let part2 = value.high >>> 24;

  // ref: src/google/protobuf/io/coded_stream.cc
  let size =
    part2 === 0 ?
      part1 === 0 ?
        part0 < 1 << 14 ?
          part0 < 1 << 7 ? 1 : 2 :
          part0 < 1 << 21 ? 3 : 4 :
        part1 < 1 << 14 ?
          part1 < 1 << 7 ? 5 : 6 :
          part1 < 1 << 21 ? 7 : 8 :
      part2 < 1 << 7 ? 9 : 10;

  let offset = grow(bb, size);
  let bytes = bb.bytes;

  switch (size) {
    case 10: bytes[offset + 9] = (part2 >>> 7) & 0x01;
    case 9: bytes[offset + 8] = size !== 9 ? part2 | 0x80 : part2 & 0x7F;
    case 8: bytes[offset + 7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F;
    case 7: bytes[offset + 6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F;
    case 6: bytes[offset + 5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F;
    case 5: bytes[offset + 4] = size !== 5 ? part1 | 0x80 : part1 & 0x7F;
    case 4: bytes[offset + 3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F;
    case 3: bytes[offset + 2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F;
    case 2: bytes[offset + 1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F;
    case 1: bytes[offset] = size !== 1 ? part0 | 0x80 : part0 & 0x7F;
  }
}

function readVarint32ZigZag(bb: ByteBuffer): number {
  let value = readVarint32(bb);

  // ref: src/google/protobuf/wire_format_lite.h
  return (value >>> 1) ^ -(value & 1);
}

function writeVarint32ZigZag(bb: ByteBuffer, value: number): void {
  // ref: src/google/protobuf/wire_format_lite.h
  writeVarint32(bb, (value << 1) ^ (value >> 31));
}

function readVarint64ZigZag(bb: ByteBuffer): Long {
  let value = readVarint64(bb, /* unsigned */ false);
  let low = value.low;
  let high = value.high;
  let flip = -(low & 1);

  // ref: src/google/protobuf/wire_format_lite.h
  return {
    low: ((low >>> 1) | (high << 31)) ^ flip,
    high: (high >>> 1) ^ flip,
    unsigned: false,
  };
}

function writeVarint64ZigZag(bb: ByteBuffer, value: Long): void {
  let low = value.low;
  let high = value.high;
  let flip = high >> 31;

  // ref: src/google/protobuf/wire_format_lite.h
  writeVarint64(bb, {
    low: (low << 1) ^ flip,
    high: ((high << 1) | (low >>> 31)) ^ flip,
    unsigned: false,
  });
}
